package com.vehiclemanagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vehiclemanagement.dto.UserDTO;
import com.vehiclemanagement.entity.User;
import com.vehiclemanagement.mapper.UserMapper;
import com.vehiclemanagement.service.UserService;
import com.vehiclemanagement.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public String login(String username, String password) {
        log.info("用户登录: username={}", username);
        
        try {
            // 进行身份验证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password));
            
            // 生成JWT令牌
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            
            // 获取用户信息
            User user = userMapper.selectByUsername(username);
            
            // 更新最后登录时间
            if (user != null) {
                user.setLastLoginTime(LocalDateTime.now());
                userMapper.updateById(user);
            }
            
            // 添加自定义claims
            Map<String, Object> claims = new HashMap<>();
            if (user != null) {
                claims.put("userId", user.getId());
                claims.put("role", user.getRole());
            }
            
            return jwtUtil.generateToken(username, claims);
        } catch (DisabledException e) {
            log.error("用户已禁用: {}", e.getMessage());
            throw new RuntimeException("用户已禁用");
        } catch (BadCredentialsException e) {
            log.error("用户名或密码错误: {}", e.getMessage());
            throw new RuntimeException("用户名或密码错误");
        } catch (Exception e) {
            log.error("登录失败: {}", e.getMessage());
            throw new RuntimeException("登录失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean register(UserDTO userDTO) {
        log.info("用户注册: {}", userDTO.getUsername());
        
        // 检查用户名是否已存在
        int count = userMapper.checkUsernameExists(userDTO.getUsername());
        if (count > 0) {
            log.error("用户名已存在: {}", userDTO.getUsername());
            throw new RuntimeException("用户名已存在");
        }
        
        // 创建新用户
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        
        // 设置默认值
        user.setStatus(1);  // 启用状态
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setDelFlag(0);  // 未删除
        
        // 如果未指定角色，默认为普通用户
        if (user.getRole() == null) {
            user.setRole(2);  // 普通用户
        }
        
        return save(user);
    }

    @Override
    @Transactional
    public boolean updateUserInfo(UserDTO userDTO) {
        log.info("更新用户信息: id={}", userDTO.getId());
        
        if (userDTO.getId() == null) {
            log.error("用户ID不能为空");
            throw new RuntimeException("用户ID不能为空");
        }
        
        // 获取原用户信息
        User existingUser = getById(userDTO.getId());
        if (existingUser == null) {
            log.error("用户不存在: id={}", userDTO.getId());
            throw new RuntimeException("用户不存在");
        }
        
        // 如果修改了用户名，检查是否已存在
        if (StringUtils.hasText(userDTO.getUsername()) && !userDTO.getUsername().equals(existingUser.getUsername())) {
            int count = userMapper.checkUsernameExists(userDTO.getUsername());
            if (count > 0) {
                log.error("用户名已存在: {}", userDTO.getUsername());
                throw new RuntimeException("用户名已存在");
            }
            existingUser.setUsername(userDTO.getUsername());
        }
        
        // 更新密码（如果有）
        if (StringUtils.hasText(userDTO.getPassword())) {
            existingUser.setPassword(passwordEncoder.encode(userDTO.getPassword()));
        }
        
        // 更新其他字段
        if (StringUtils.hasText(userDTO.getRealName())) {
            existingUser.setRealName(userDTO.getRealName());
        }
        if (StringUtils.hasText(userDTO.getPhone())) {
            existingUser.setPhone(userDTO.getPhone());
        }
        if (StringUtils.hasText(userDTO.getEmail())) {
            existingUser.setEmail(userDTO.getEmail());
        }
        if (userDTO.getRole() != null) {
            existingUser.setRole(userDTO.getRole());
        }
        if (userDTO.getStatus() != null) {
            existingUser.setStatus(userDTO.getStatus());
        }
        
        existingUser.setUpdateTime(LocalDateTime.now());
        
        return updateById(existingUser);
    }

    @Override
    public User getUserById(Long id) {
        return getById(id);
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public IPage<User> pageUsers(Integer current, Integer size, String searchTerm, Integer role, Integer status) {
        Page<User> page = new Page<>(current, size);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        
        // 未删除的用户
        queryWrapper.eq(User::getDelFlag, 0);
        
        // 搜索条件
        if (StringUtils.hasText(searchTerm)) {
            queryWrapper.and(wrapper -> 
                wrapper.like(User::getUsername, searchTerm)
                       .or().like(User::getRealName, searchTerm)
                       .or().like(User::getPhone, searchTerm)
                       .or().like(User::getEmail, searchTerm)
            );
        }
        
        // 角色过滤
        if (role != null) {
            queryWrapper.eq(User::getRole, role);
        }
        
        // 状态过滤
        if (status != null) {
            queryWrapper.eq(User::getStatus, status);
        }
        
        // 按创建时间排序
        queryWrapper.orderByDesc(User::getCreateTime);
        
        return page(page, queryWrapper);
    }

    @Override
    @Transactional
    public boolean updateUserStatus(Long id, Integer status) {
        log.info("更新用户状态: id={}, status={}", id, status);
        
        if (id == null || status == null) {
            log.error("用户ID和状态不能为空");
            throw new RuntimeException("用户ID和状态不能为空");
        }
        
        User user = getById(id);
        if (user == null) {
            log.error("用户不存在: id={}", id);
            throw new RuntimeException("用户不存在");
        }
        
        user.setStatus(status);
        user.setUpdateTime(LocalDateTime.now());
        
        return updateById(user);
    }

    @Override
    @Transactional
    public boolean resetPassword(Long id, String newPassword) {
        log.info("重置用户密码: id={}", id);
        
        if (id == null || !StringUtils.hasText(newPassword)) {
            log.error("用户ID和新密码不能为空");
            throw new RuntimeException("用户ID和新密码不能为空");
        }
        
        User user = getById(id);
        if (user == null) {
            log.error("用户不存在: id={}", id);
            throw new RuntimeException("用户不存在");
        }
        
        user.setPassword(passwordEncoder.encode(newPassword));
        user.setUpdateTime(LocalDateTime.now());
        
        return updateById(user);
    }

    @Override
    @Transactional
    public boolean deleteUser(Long id) {
        log.info("删除用户: id={}", id);
        
        if (id == null) {
            log.error("用户ID不能为空");
            throw new RuntimeException("用户ID不能为空");
        }
        
        User user = getById(id);
        if (user == null) {
            log.error("用户不存在: id={}", id);
            throw new RuntimeException("用户不存在");
        }
        
        // 逻辑删除
        user.setDelFlag(1);
        user.setUpdateTime(LocalDateTime.now());
        
        return updateById(user);
    }
} 